"""
动态星空特效组件 - 为PyQt应用程序添加璀璨星河背景特效
"""

import random
import math
from PySide2.QtWidgets import QWidget
from PySide2.QtCore import QTimer, Qt
from PySide2.QtGui import QPainter, QPen, QBrush, QRadialGradient, QColor


class Star:
    """单个星星对象"""
    
    def __init__(self, width, height, twinkle_speed_multiplier=1.0):
        # 更多样化的星星大小 - 有大有小
        size_type = random.random()
        if size_type < 0.6:
            # 60% 小星星
            self.size = random.uniform(0.5, 2.0)
            self.glow_multiplier = 2
        elif size_type < 0.85:
            # 25% 中等星星
            self.size = random.uniform(1.5, 4.0)
            self.glow_multiplier = 3
        else:
            # 15% 大星星
            self.size = random.uniform(2.5, 6.0)
            self.glow_multiplier = 4
        
        # 更多样化的亮度 - 有亮有暗
        brightness_type = random.random()
        if brightness_type < 0.3:
            # 30% 暗星
            self.base_brightness = random.uniform(0.1, 0.5)
        elif brightness_type < 0.7:
            # 40% 中等亮度
            self.base_brightness = random.uniform(0.4, 0.9)
        else:
            # 30% 亮星
            self.base_brightness = random.uniform(0.6, 1.0)
        
        self.brightness = self.base_brightness
        self.max_brightness = min(1.0, self.base_brightness + 0.6)
        self.min_brightness = max(0.1, self.base_brightness - 0.3)
        
        # 星星颜色 - 符合科技蓝色调
        colors = [
            QColor(255, 255, 255),  # 纯白
            QColor(230, 243, 255),  # 冰蓝白
            QColor(0, 212, 255),    # 青蓝
            QColor(78, 205, 196),   # 青绿
            QColor(69, 183, 209),   # 天蓝
            QColor(150, 206, 180),  # 薄荷绿
            QColor(255, 215, 0),    # 金色
            QColor(255, 107, 157)   # 粉红
        ]
        self.color = random.choice(colors)
        
        # 位置
        self.x = random.uniform(0, width)
        self.y = random.uniform(0, height)
        
        # 闪烁参数
        self.twinkle_speed = random.uniform(0.01, 0.04) * twinkle_speed_multiplier
        self.twinkle_phase = random.uniform(0, math.pi * 2)
        self.twinkle_intensity = random.uniform(0.4, 0.8)
        self.current_speed_multiplier = twinkle_speed_multiplier
        
    def update(self):
        """更新星星状态"""
        # 持续闪烁效果
        self.twinkle_phase += self.twinkle_speed
        
        # 使用正弦波创建自然的闪烁效果
        twinkle = math.sin(self.twinkle_phase) * self.twinkle_intensity
        self.brightness = self.base_brightness + twinkle * (self.max_brightness - self.min_brightness)
        
        # 确保亮度在合理范围内
        self.brightness = max(self.min_brightness, min(self.max_brightness, self.brightness))
        
        # 偶尔添加随机闪烁突变，让效果更生动
        if random.random() < 0.002:
            self.brightness += random.uniform(-0.3, 0.3)
            self.brightness = max(self.min_brightness, min(self.max_brightness, self.brightness))


class StarfieldEffect(QWidget):
    """动态星空特效组件"""
    
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setAttribute(Qt.WA_TransparentForMouseEvents)
        self.setWindowFlags(Qt.FramelessWindowHint)
        
        # 特效设置
        self.enabled = True
        self.star_density = 'medium'  # low, medium, high
        self.twinkle_speed = 'normal'  # slow, normal, fast
        
        # 星星列表
        self.stars = []
        
        # 动画定时器
        self.timer = QTimer()
        self.timer.timeout.connect(self.update_animation)
        self.timer.start(16)  # 约60FPS
        
        # 初始化星星
        self.init_stars()
        
    def get_star_count(self):
        """根据密度设置获取星星数量"""
        if not self.parent():
            return 100
            
        area = self.parent().width() * self.parent().height()
        density_map = {
            'low': 0.00012,
            'medium': 0.0002,
            'high': 0.00035
        }
        density = density_map.get(self.star_density, 0.0002)
        return int(area * density)
    
    def get_twinkle_speed_multiplier(self):
        """获取闪烁速度倍数"""
        speed_map = {
            'slow': 0.5,
            'normal': 1.0,
            'fast': 2.0
        }
        return speed_map.get(self.twinkle_speed, 1.0)
    
    def init_stars(self):
        """初始化星星"""
        if not self.parent():
            return
            
        self.stars.clear()
        star_count = self.get_star_count()
        speed_multiplier = self.get_twinkle_speed_multiplier()
        
        width = self.parent().width()
        height = self.parent().height()
        
        for _ in range(star_count):
            star = Star(width, height, speed_multiplier)
            self.stars.append(star)
    
    def set_enabled(self, enabled):
        """设置特效开关"""
        self.enabled = enabled
        if enabled:
            self.timer.start(16)
            self.show()
        else:
            self.timer.stop()
            self.hide()
    
    def set_star_density(self, density):
        """设置星星密度"""
        if density in ['low', 'medium', 'high']:
            self.star_density = density
            self.init_stars()
    
    def set_twinkle_speed(self, speed):
        """设置闪烁速度"""
        if speed in ['slow', 'normal', 'fast']:
            self.twinkle_speed = speed
            speed_multiplier = self.get_twinkle_speed_multiplier()
            
            # 更新所有星星的闪烁速度
            for star in self.stars:
                base_speed = star.twinkle_speed / (star.current_speed_multiplier or 1)
                star.twinkle_speed = base_speed * speed_multiplier
                star.current_speed_multiplier = speed_multiplier
    
    def update_animation(self):
        """更新动画"""
        if not self.enabled:
            return
            
        # 更新所有星星
        for star in self.stars:
            star.update()
        
        # 重绘
        self.update()
    
    def resizeEvent(self, event):
        """窗口大小改变时重新初始化星星"""
        super().resizeEvent(event)
        if self.parent():
            self.setGeometry(0, 0, self.parent().width(), self.parent().height())
            self.init_stars()
    
    def paintEvent(self, event):
        """绘制星空特效"""
        if not self.enabled or not self.stars:
            return
            
        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing)
        painter.setRenderHint(QPainter.SmoothPixmapTransform)
        
        for star in self.stars:
            self.draw_star(painter, star)
    
    def draw_star(self, painter, star):
        """绘制单个星星"""
        painter.save()
        
        # 外层大光晕 - 营造梦幻效果
        outer_glow_size = star.size * star.glow_multiplier * 2
        outer_glow = QRadialGradient(star.x, star.y, outer_glow_size)
        
        color = star.color
        outer_glow.setColorAt(0, QColor(color.red(), color.green(), color.blue(), int(star.brightness * 76)))
        outer_glow.setColorAt(0.4, QColor(color.red(), color.green(), color.blue(), int(star.brightness * 38)))
        outer_glow.setColorAt(1, QColor(color.red(), color.green(), color.blue(), 0))
        
        painter.setBrush(QBrush(outer_glow))
        painter.setPen(Qt.NoPen)
        painter.drawEllipse(int(star.x - outer_glow_size), int(star.y - outer_glow_size),
                          int(outer_glow_size * 2), int(outer_glow_size * 2))
        
        # 中层光晕
        mid_glow_size = star.size * star.glow_multiplier
        mid_glow = QRadialGradient(star.x, star.y, mid_glow_size)
        
        mid_glow.setColorAt(0, QColor(color.red(), color.green(), color.blue(), int(star.brightness * 153)))
        mid_glow.setColorAt(0.6, QColor(color.red(), color.green(), color.blue(), int(star.brightness * 76)))
        mid_glow.setColorAt(1, QColor(color.red(), color.green(), color.blue(), 0))
        
        painter.setBrush(QBrush(mid_glow))
        painter.drawEllipse(int(star.x - mid_glow_size), int(star.y - mid_glow_size),
                          int(mid_glow_size * 2), int(mid_glow_size * 2))
        
        # 星星核心 - 白色亮点
        core_size = star.size * 1.2
        core_glow = QRadialGradient(star.x, star.y, core_size)
        
        core_glow.setColorAt(0, QColor(255, 255, 255, int(star.brightness * 255)))
        core_glow.setColorAt(0.7, QColor(255, 255, 255, int(star.brightness * 204)))
        core_glow.setColorAt(1, QColor(255, 255, 255, 0))
        
        painter.setBrush(QBrush(core_glow))
        painter.drawEllipse(int(star.x - core_size), int(star.y - core_size),
                          int(core_size * 2), int(core_size * 2))
        
        # 最内层核心点
        inner_size = star.size * 0.3
        painter.setBrush(QBrush(QColor(255, 255, 255, int(star.brightness * 255))))
        painter.drawEllipse(int(star.x - inner_size), int(star.y - inner_size),
                          int(inner_size * 2), int(inner_size * 2))
        
        painter.restore()
